package cn.wolfcode.shop.cloud.service.impl;

import cn.wolfcode.shop.cloud.common.BusinessException;
import cn.wolfcode.shop.cloud.common.Result;
import cn.wolfcode.shop.cloud.domain.Good;
import cn.wolfcode.shop.cloud.domain.SeckillGood;
import cn.wolfcode.shop.cloud.mapper.SeckillGoodMapper;
import cn.wolfcode.shop.cloud.redis.RedisService;
import cn.wolfcode.shop.cloud.redis.SeckillKeyPrefix;
import cn.wolfcode.shop.cloud.service.ISeckillGoodService;
import cn.wolfcode.shop.cloud.vo.SeckillGoodVo;
import cn.wolfcode.shop.cloud.web.feign.GoodFeignApi;
import cn.wolfcode.shop.cloud.util.SeckillGoodsCodeMsg;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class SeckillGoodServiceImpl implements ISeckillGoodService {
    @Autowired
    private SeckillGoodMapper seckillGoodMapper;
    @Autowired
    private GoodFeignApi goodFeignApi;
    @Autowired
    private RedisService redisService;

    @Override
    public List<SeckillGoodVo> query() {
        //1.首先查询出来秒杀商品的数据
        List<SeckillGood> seckillGoods = seckillGoodMapper.list();
        //2.把商品的id封装到一个set集合中

        return common(seckillGoods);
    }

    public List<SeckillGoodVo> common(List<SeckillGood> seckillGoods){
        //存放商品id的信息
        Set<Long> goodIds = new HashSet<>();
        for (SeckillGood seckillGood :seckillGoods){
            goodIds.add(seckillGood.getGoodId());
        }
        //把set集合里的数据转换成list集合
        ArrayList<Long> ids = new ArrayList<>(goodIds);
        //远程到商品服务中去拿商品的数据
        Result<List<Good>> listResult = goodFeignApi.queryByIds(ids);
        if (listResult==null||listResult.getCode()!=200){
            throw new BusinessException(SeckillGoodsCodeMsg.REMOTE_GOOD_ERROR);
        }
        List<Good> goods = listResult.getData();
        //把goods 放到map集合中 key是good的Id value是good
        Map<Long,Good> map = new HashMap<>();
        for (Good good : goods){
            map.put(good.getId(), good);
        }

        ArrayList<SeckillGoodVo> goodVos = new ArrayList<>();
        //遍历设置列表字段属性
        for (SeckillGood seckillGood : seckillGoods) {
            SeckillGoodVo seckillGoodVo = new SeckillGoodVo();
            Good good = map.get(seckillGood.getGoodId());
            seckillGoodVo.setGoodDetail(good.getGoodDetail());
            seckillGoodVo.setGoodImg(good.getGoodImg());
            seckillGoodVo.setGoodName(good.getGoodName());
            seckillGoodVo.setGoodPrice(good.getGoodPrice());
            seckillGoodVo.setGoodStock(good.getGoodStock());
            seckillGoodVo.setGoodTitle(good.getGoodTitle());
            seckillGoodVo.setGoodId(good.getId());
            seckillGoodVo.setEndDate(seckillGood.getEndDate());
            seckillGoodVo.setId(seckillGood.getId());
            seckillGoodVo.setSeckillPrice(seckillGood.getSeckillPrice());
            seckillGoodVo.setStockCount(seckillGood.getStockCount());
            seckillGoodVo.setStartDate(seckillGood.getStartDate());
            goodVos.add(seckillGoodVo);
        }
        return goodVos;
    }

    @Override
    public SeckillGoodVo findById(Long seckillId) {
        SeckillGood seckillGood = seckillGoodMapper.findById(seckillId);
        List<SeckillGood> list = new ArrayList<>();
        list.add(seckillGood);

        List<SeckillGoodVo> goodVos = common(list);
        return goodVos.get(0);

    }

    @Override
    public int decrCount(Long seckillId) {
        return seckillGoodMapper.decrCount(seckillId);
    }

    @Override
    public SeckillGoodVo findByIdCache(Long seckillId) {
        return redisService.hget(SeckillKeyPrefix.SECKILL_GOOD_HASH, "", seckillId+"", SeckillGoodVo.class);
    }

    @Override
    public List<SeckillGoodVo> queryCache() {
        Map<String, SeckillGoodVo> seckillGoodVoMap = redisService.hgetAll(SeckillKeyPrefix.SECKILL_GOOD_HASH, "", SeckillGoodVo.class);
        return new ArrayList<SeckillGoodVo>(seckillGoodVoMap.values());
    }

    @Override
    public void incrCount(Long goodId) {
        seckillGoodMapper.incrCount(goodId);
    }

    @Override
    public void syncRedisCount(Long goodId) {
        SeckillGoodVo seckillGoodVo = findById(goodId);

        redisService.set(SeckillKeyPrefix.SECKILL_STOCK,seckillGoodVo.getId()+"",seckillGoodVo.getStockCount());
        //把秒杀商品也放入到redis当中
        redisService.hset(SeckillKeyPrefix.SECKILL_GOOD_HASH,"",seckillGoodVo.getId()+"",seckillGoodVo);
    }


}
